package com.zero.zerocat;

import com.zero.servlet.ZeroServlet;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpRequest;

import java.util.Map;

public class ZeroCatHandler extends ChannelInboundHandlerAdapter {

    private Map<String, String> nameToClassNameMap;

    private Map<String, ZeroServlet> nameToServletMap;

    public ZeroCatHandler(Map<String, String> nameToClassNameMap, Map<String, ZeroServlet> nameToServletMap) {
        this.nameToClassNameMap = nameToClassNameMap;
        this.nameToServletMap = nameToServletMap;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 当msg是HttpRequest类型的时候，我们才对其进行处理，否则不进行处理
        if (msg instanceof HttpRequest) {
            HttpRequest request = (HttpRequest) msg;
            // 从request的uri中解析出servlet名称，比如 uri=/testservlet/cook?name=salad，其中testservlet为servlet名称（约定使用小写的uri）
            String uri = request.uri();
            String servletName;
            if (uri.substring(1).contains("/")) {
                servletName = uri.substring(1).split("/")[0];
            } else {
                servletName = uri.substring(1).split("\\?")[0];
            }
            // 创建ZeroServlet，默认为DefaultZeroServlet
            ZeroServlet servlet = new DefaultZeroServlet();
            // 先从nameToServletMap中获取servletName对应的servlet实例
            if (nameToServletMap.containsKey(servletName)) {
                servlet = nameToServletMap.get(servletName);
            } else if (nameToClassNameMap.containsKey(servletName)) {
                synchronized (this) {
                    // 如果没有获取到servlet实例，则从nameToClassNameMap中获取对应的全限定类名
                    String servletClassName = nameToClassNameMap.get(servletName);
                    // 通过server的全限定类名创建servlet实例，并将servlet实例放在nameToServletMap中
                    servlet = (ZeroServlet) Class.forName(servletClassName).newInstance();
                    nameToServletMap.put(servletName, servlet);
                }
            }
            HttpZeroRequest httpZeroRequest = new HttpZeroRequest(request);
            HttpZeroResponse httpZeroResponse = new HttpZeroResponse(request, ctx);
            if ("GET".equalsIgnoreCase(httpZeroRequest.getMethod())) {
                servlet.doGet(httpZeroRequest, httpZeroResponse);
            }
            if ("POST".equalsIgnoreCase(httpZeroRequest.getMethod())) {
                servlet.doPost(httpZeroRequest, httpZeroResponse);
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
